package net.cardgame.orcalecard.utils;

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import net.cardgame.orcalecard.bean.DeckBean;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import android.util.Log;

public class XmlParser {
	/**
	 * Method to get xml content from url HTTP Get request
	 * */
	public ArrayList<DeckBean> Parser(String url) {
		String xml = null;
		ArrayList<DeckBean> list = new ArrayList<DeckBean>();
		try {
			// request method is GET
			DefaultHttpClient httpClient = new DefaultHttpClient();
			HttpGet httpGet = new HttpGet(url);
			HttpResponse httpResponse = httpClient.execute(httpGet);
			HttpEntity httpEntity = httpResponse.getEntity();
			xml = EntityUtils.toString(httpEntity);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		Document doc = getDomElement(xml);
		NodeList cardList = doc.getElementsByTagName("Card");
		for (int i = 0; i < cardList.getLength(); i++) {
			Node nodeCard = cardList.item(i);
			Element CardElement = (Element) nodeCard;
			DeckBean deckBean = new DeckBean();
			deckBean.deckId = Integer.parseInt(CardElement
					.getAttribute("cardId"));
			deckBean.deckName = CardElement.getAttribute("name");
			deckBean.isFree = Boolean.getBoolean(CardElement
					.getAttribute("free"));
			String date = CardElement.getAttribute("releaseDate");
			String[] str = date.split(".");
			Date d = new Date();
			d.setDate(Integer.parseInt(str[2]));
			d.setMonth(Integer.parseInt(str[1]) - 1);
			d.setYear(Integer.parseInt(str[0]));
			deckBean.releaseDate = d;
			deckBean.inAppPurchaseId = CardElement.getAttribute("purchaseId");
			deckBean.deckPrice = Integer.parseInt(CardElement
					.getAttribute("price"));
			deckBean.cardNumber = Integer.parseInt(CardElement
					.getAttribute("numberOfCardsNewVersion"));
			deckBean.pathServerDownload = CardElement.getAttribute("server");
			list.add(deckBean);
		}
		return list;
	}

	public String putToXmlString(ArrayList<DeckBean> list) {
		String result = "";
		try {
			DocumentBuilderFactory docFactory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
			// root elements
			Document doc = docBuilder.newDocument();
			Element rootElement = doc.createElement("root");
			doc.appendChild(rootElement);
			for (DeckBean deckBean : list) {

				// Card elements
				Element card = doc.createElement("Card");
				rootElement.appendChild(card);
				// set cardId Attribute for Card element
				card.setAttribute("cardId", deckBean.deckId + "");
				// set name Attribute for Card element
				card.setAttribute("name", deckBean.deckName);
				// set free Attribute for Card element
				card.setAttribute("free", deckBean.isFree ? "1" : "0");
				// set releaseDate Attribute for Card element
				card.setAttribute("releaseDate",
						deckBean.releaseDate.toString());
				// set purchaseId Attribute for Card element
				card.setAttribute("purchaseId", deckBean.inAppPurchaseId);
				// set price Attribute for Card element
				card.setAttribute("price", deckBean.deckPrice + "");
				// set numberOfCards Attribute for Card element
				card.setAttribute("numberOfCards", deckBean.cardNumber + "");
				// set server Attribute for Card element
				card.setAttribute("server", deckBean.pathServerDownload);
				// set isUnlock Attribute for Card element
				card.setAttribute("isUnlock", deckBean.isUnlock ? "1" : "0");
				// set percentDownloaded for Card element
				card.setAttribute("percentDownloaded",
						deckBean.percentDownloaded + "");
			}
			result = toString(doc);

		} catch (Exception e) {
			// TODO: handle exception
		}
		return result;
	}

	public String toString(Document doc) {
		try {
			StringWriter sw = new StringWriter();
			TransformerFactory tf = TransformerFactory.newInstance();
			Transformer transformer = tf.newTransformer();
			transformer
					.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
			transformer.setOutputProperty(OutputKeys.METHOD, "xml");
			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
			transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");

			transformer.transform(new DOMSource(doc), new StreamResult(sw));
			return sw.toString();
		} catch (Exception ex) {
			throw new RuntimeException("Error converting to String", ex);
		}
	}

	public ArrayList<DeckBean> getDeckBeans(String configXML) {
		ArrayList<DeckBean> list = new ArrayList<DeckBean>();
		try {
			Document doc = getDomElement(configXML);
			NodeList cardList = doc.getElementsByTagName("Card");
			int minute = 60;
			for (int i = 0; i < cardList.getLength(); i++) {
				Node nodeCard = cardList.item(i);
				Element CardElement = (Element) nodeCard;
				DeckBean deckBean = new DeckBean();
				deckBean.deckId = Integer.parseInt(CardElement
						.getAttribute("cardId"));
				deckBean.deckName = CardElement.getAttribute("name");
				if (Integer.parseInt(CardElement.getAttribute("free")) == 1)
					deckBean.isFree = true;
				String date = CardElement.getAttribute("releaseDate");
				String delimiter = "\\.";
				String[] str = date.split(delimiter);
				int year = Integer.parseInt(str[0]);
				int month = Integer.parseInt(str[1]) - 1;
				int day = Integer.parseInt(str[2]);
				deckBean.releaseDate = new Date(year - 1900, month, day);
				// Utils.ELog("release Date:" + deckBean.deckId,
				// deckBean.releaseDate.toGMTString());
				deckBean.buyDate = new Date(0, 1, 1);
				deckBean.lastUsedDate = new Date(0, 1, 1);
				if (minute > 0) {
					deckBean.releaseDate.setMinutes(minute);
					deckBean.buyDate.setMinutes(minute);
					deckBean.lastUsedDate.setMinutes(minute);
				}
				minute--;
				deckBean.inAppPurchaseId = CardElement
						.getAttribute("purchaseId");
				deckBean.deckPrice = Integer.parseInt(CardElement
						.getAttribute("price"));
				deckBean.cardNumber = Integer.parseInt(CardElement
						.getAttribute("numberOfCardsNewVersion"));
				deckBean.pathServerDownload = CardElement
						.getAttribute("server");
				if (CardElement.hasAttribute("isUnlock")) {
					if (Integer.parseInt(CardElement.getAttribute("isUnlock")) == 1)
						deckBean.isUnlock = true;
				}
				if (CardElement.hasAttribute("percentDownloaded")) {
					deckBean.percentDownloaded = Integer.parseInt(CardElement
							.getAttribute("percentDownloaded"));
				}
				list.add(deckBean);
			}
		} catch (Exception ex) {
		}
		return list;
	}

	public Document getDomElement(String xml) {

		Document doc = null;
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		try {
			DocumentBuilder db = dbf.newDocumentBuilder();

			InputSource is = new InputSource();
			is.setCharacterStream(new StringReader(xml));
			doc = (Document) db.parse(is);

		} catch (ParserConfigurationException e) {
			Log.e("Error: ", e.getMessage());
			return null;
		} catch (SAXException e) {
			Log.e("Error: ", e.getMessage());
			return null;
		} catch (IOException e) {
			Log.e("Error: ", e.getMessage());
			return null;
		}
		return doc;
	}
}
